package com.example;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.vo.CommandLineArgs;
import com.example.vo.NexusAssetInfo;
import com.example.vo.NexusFileInfo;

/**
 * Nexus3 文件列表获取器
 * 使用Nexus3的分页API接口获取指定仓库的所有文件信息
 */
public class NexusFileListFetcher {

    private static final String DEFAULT_OUTPUT_FILE = "./nexus_files_list.json";
    private static final int MAX_RETRY_COUNT = 3;
    private static final int RETRY_INTERVAL_MS = 1000;

    public static void main(String[] args) {
        try {
            // 解析命令行参数
            CommandLineArgs cmdArgs = HttpUtils.parseCommandLineArgs(args);
            
            // 设置默认的本地路径
            if (cmdArgs.getLocalPath() == null) {
                cmdArgs.setLocalPath(DEFAULT_OUTPUT_FILE);
            }

            // 检查必要参数
            HttpUtils.checkRequiredParams(cmdArgs);

            // 获取仓库中的所有文件信息
            List<NexusFileInfo> allFiles = fetchAllFilesFromRepository(cmdArgs);

            // 将文件信息保存到JSON文件
            saveFilesListToJson(allFiles, cmdArgs.getLocalPath());

            System.out.println("[INFO] 成功获取仓库 '" + cmdArgs.getRepositoryName() + "' 的所有文件信息，共 " + allFiles.size() + " 个文件");
            System.out.println("[INFO] 文件信息已保存到: " + cmdArgs.getLocalPath());

        } catch (Exception e) {
            System.err.println("[ERROR] " + e.getMessage());
            e.printStackTrace();
            HttpUtils.showHelp();
            System.exit(1);
        }
    }

    /**
     * 使用分页API获取仓库中的所有文件信息
     */
    private static List<NexusFileInfo> fetchAllFilesFromRepository(CommandLineArgs cmdArgs) throws Exception {
        List<NexusFileInfo> allFiles = new ArrayList<>();
        String continuationToken = null;
        int pageCount = 0;
        int retryCount = 0;
        
        // 由于vo.CommandLineArgs没有pagesDir字段，我们使用固定路径
        String pagesDir = "./nexus_pages";

        // 确保分页文件保存目录存在
        File pagesDirFile = new File(pagesDir);
        if (!pagesDirFile.exists()) {
            pagesDirFile.mkdirs();
        }

        System.out.println("[INFO] 正在获取仓库 '" + cmdArgs.getRepositoryName() + "' 的所有文件信息...");
        System.out.println("[INFO] 分页文件将保存到目录: " + pagesDir);
        System.out.println("[INFO] 这个过程可能需要一些时间，请耐心等待...");

        // 基本URL
        String baseNexusApiUrl = cmdArgs.getNexusUrl() + (cmdArgs.getNexusUrl().endsWith("/") ? "" : "/") + 
                               "service/rest/v1/components?repository=" + cmdArgs.getRepositoryName();

        // 进行分页获取
        while (true) {
            try {
                // 构建带分页参数的URL
                String nexusApiUrl = baseNexusApiUrl;
                if (continuationToken != null) {
                    nexusApiUrl += "&continuationToken=" + continuationToken;
                }

                System.out.println("[INFO] 获取第 " + (++pageCount) + " 页数据...");
                System.out.println("[INFO] 请求URL: " + nexusApiUrl);

                // 发送HTTP请求
                String responseJson;
                try {
                    responseJson = HttpUtils.sendGetRequest(
                    nexusApiUrl, 
                    cmdArgs.getUsername(), 
                    cmdArgs.getPassword(), 
                    cmdArgs.getProxyHost(), 
                    cmdArgs.getProxyPort(), 
                    cmdArgs.getProxyUsername(), 
                    cmdArgs.getProxyPassword()
                );
                } catch (Exception e) {
                    // 添加更具体的错误信息
                    if (e.getMessage().contains("HTTP请求失败")) {
                        throw new RuntimeException("获取文件列表失败，" + e.getMessage() + ", 请检查Nexus地址、用户名、密码和仓库名称是否正确。", e);
                    }
                    throw e;
                }

                // 解析响应 - 使用fastjson
                JSONObject jsonObject = JSON.parseObject(responseJson);
                JSONArray items = jsonObject.getJSONArray("items");

                if (items == null || items.size() == 0) {
                    System.out.println("[INFO] 没有更多数据了。");
                    break;
                }

                // 处理当前页的数据
                List<NexusFileInfo> pageFiles = new ArrayList<>();
                for (int i = 0; i < items.size(); i++) {
                    JSONObject component = items.getJSONObject(i);
                    NexusFileInfo fileInfo = parseComponent(component);
                    if (fileInfo != null) {
                        allFiles.add(fileInfo);
                        pageFiles.add(fileInfo);
                    }
                }

                // 保存当前页数据到单独的文件
                String pageFileName = pagesDir + File.separator + "page_" + pageCount + ".json";
                savePageDataToJson(pageFiles, pageFileName);
                System.out.println("[INFO] 第 " + pageCount + " 页数据已保存到: " + pageFileName);

                // 检查是否有下一页
                if (jsonObject.containsKey("continuationToken")) {
                    String token = jsonObject.getString("continuationToken");
                    if (token != null && !token.isEmpty() && !"null".equals(token)) {
                        continuationToken = token;
                        retryCount = 0; // 重置重试计数
                        continue;
                    }
                }

                // 没有更多页了
                break;

            } catch (Exception e) {
                System.err.println("[ERROR] 获取文件列表出错: " + e.getMessage());
                
                // 重试机制
                if (retryCount < MAX_RETRY_COUNT) {
                    retryCount++;
                    System.out.println("[INFO] 第 " + retryCount + " 次重试...");
                    Thread.sleep(RETRY_INTERVAL_MS * retryCount); // 指数退避
                    continue;
                } else {
                    throw new RuntimeException("达到最大重试次数，获取文件列表失败", e);
                }
            }
        }

        System.out.println("[INFO] 所有分页数据获取完成，共获取了 " + pageCount + " 页数据");
        return allFiles;
    }

    /**
     * 保存单页数据到JSON文件
     */
    private static void savePageDataToJson(List<NexusFileInfo> pageFiles, String outputFilePath) throws Exception {
        // 确保输出目录存在
        File outputFile = new File(outputFilePath);
        File parentDir = outputFile.getParentFile();
        if (parentDir != null && !parentDir.exists()) {
            parentDir.mkdirs();
        }

        // 创建结果对象
        JSONObject result = new JSONObject();
        result.put("pageSize", pageFiles.size());
        result.put("files", pageFiles);

        // 使用fastjson格式化输出
        String jsonString = JSON.toJSONString(result, true);

        // 写入文件
        try (FileOutputStream outputStream = new FileOutputStream(outputFilePath)) {
            outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
        }
    }

    /**
     * 解析组件信息 - 使用fastjson
     */
    private static NexusFileInfo parseComponent(JSONObject component) {
        try {
            NexusFileInfo fileInfo = new NexusFileInfo();

            // 获取基本信息
            if (component.containsKey("id")) {
                fileInfo.setComponentId(component.getString("id"));
            }

            if (component.containsKey("name")) {
                fileInfo.setName(component.getString("name"));
            }

            if (component.containsKey("group")) {
                fileInfo.setGroup(component.getString("group"));
            }

            if (component.containsKey("version")) {
                fileInfo.setVersion(component.getString("version"));
            }

            if (component.containsKey("format")) {
                fileInfo.setFormat(component.getString("format"));
            }

            if (component.containsKey("assets")) {
                JSONArray assets = component.getJSONArray("assets");
                List<NexusAssetInfo> assetInfoList = new ArrayList<>();

                for (int i = 0; i < assets.size(); i++) {
                    JSONObject asset = assets.getJSONObject(i);
                    NexusAssetInfo assetInfo = new NexusAssetInfo();

                    if (asset.containsKey("id")) {
                        assetInfo.setId(asset.getString("id"));
                    }

                    if (asset.containsKey("path")) {
                        assetInfo.setPath(asset.getString("path"));
                    }

                    if (asset.containsKey("downloadUrl")) {
                        assetInfo.setDownloadUrl(asset.getString("downloadUrl"));
                    }

                    if (asset.containsKey("checksum")) {
                        JSONObject checksum = asset.getJSONObject("checksum");
                        if (checksum.containsKey("sha1")) {
                            assetInfo.setSha1(checksum.getString("sha1"));
                        }
                        if (checksum.containsKey("md5")) {
                            assetInfo.setMd5(checksum.getString("md5"));
                        }
                    }

                    if (asset.containsKey("contentType")) {
                        assetInfo.setContentType(asset.getString("contentType"));
                    }

                    if (asset.containsKey("lastModified")) {
                        assetInfo.setLastModified(asset.getString("lastModified"));
                    }

                    if (asset.containsKey("size")) {
                        assetInfo.setSize(asset.getLong("size"));
                    }

                    assetInfoList.add(assetInfo);
                }

                fileInfo.setAssets(assetInfoList);
            }

            return fileInfo;

        } catch (Exception e) {
            System.err.println("[WARN] 解析组件信息出错: " + e.getMessage());
            return null;
        }
    }

    /**
     * 将文件信息保存到JSON文件 - 使用fastjson简化JSON构建
     */
    private static void saveFilesListToJson(List<NexusFileInfo> files, String outputFilePath) throws Exception {
        // 确保输出目录存在
        File outputFile = new File(outputFilePath);
        File parentDir = outputFile.getParentFile();
        if (parentDir != null && !parentDir.exists()) {
            parentDir.mkdirs();
        }

        // 创建结果对象
        JSONObject result = new JSONObject();
        result.put("totalCount", files.size());
        result.put("files", files);

        // 使用fastjson格式化输出
        String jsonString = JSON.toJSONString(result, true);

        // 写入文件
        try (FileOutputStream outputStream = new FileOutputStream(outputFilePath)) {
            outputStream.write(jsonString.getBytes(StandardCharsets.UTF_8));
        }
    }

    /**
     * 命令行参数类
     */



}